Network Data | Social Network Analysis¶

Dr. Chan, Chun-Hsiang @ Department of Geography,
National Taiwan Normal University, Taipei, Taiwan

Graph data¶

In [1]:
# import packages
import numpy as np
import pandas as pd
import networkx as nx
import matplotlib.pyplot as plt

Direclty create a graph¶

In [2]:
# define a simple graph
star = nx.Graph([(0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6)])
line = nx.Graph([(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)])
circle = nx.Graph([(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 0)])

# preview graph
star.nodes, star.edges
Out[2]:
(NodeView((0, 1, 2, 3, 4, 5, 6)),
 EdgeView([(0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6)]))
In [3]:
# add node attributes
attr_6 = {0: "A", 1: "B", 2: "C", 3: "D", 4: "E", 5: "F"}
attr_7 = {0: "A", 1: "B", 2: "C", 3: "D", 4: "E", 5: "F", 6: "G"}

# relabel nodes
star = nx.relabel_nodes(star, attr_7)
line = nx.relabel_nodes(line, attr_6)
circle = nx.relabel_nodes(circle, attr_6)

# preview graph
star.nodes, star.edges
Out[3]:
(NodeView(('A', 'B', 'C', 'D', 'E', 'F', 'G')),
 EdgeView([('A', 'B'), ('A', 'C'), ('A', 'D'), ('A', 'E'), ('A', 'F'), ('A', 'G')]))

Create a graph through one-by-one adding¶

Create a Graph¶

In [4]:
# define a graph
# in networkx, they provides two types of graphs: undirected and directed ...
# therefore, you have to think about it before declaring a new graph
G = nx.Graph()
G
Out[4]:
<networkx.classes.graph.Graph at 0x26b26249908>

Add Node¶

In [5]:
# add node
G.add_node(1)
# preview graph
G.nodes
Out[5]:
NodeView((1,))
In [6]:
# add node
G.add_nodes_from([2,3,4,5,6])
# preview graph
G.nodes
Out[6]:
NodeView((1, 2, 3, 4, 5, 6))
In [7]:
# add node with attribute
G.add_nodes_from([(2, {'name': 'apple'}),
                  (3, {'name': 'ball'})])

Add Edge¶

In [8]:
# add edge
G.add_edge(20,30)
# preview graph
G.nodes, G.edges # <== nx will automatically add the missing nodes
Out[8]:
(NodeView((1, 2, 3, 4, 5, 6, 20, 30)), EdgeView([(20, 30)]))
In [9]:
# add edge
G.add_edge(1, 2)
# preview graph
G.nodes, G.edges
Out[9]:
(NodeView((1, 2, 3, 4, 5, 6, 20, 30)), EdgeView([(1, 2), (20, 30)]))
In [10]:
# add edge by tuple
e = (2, 3)
G.add_edge(*e)
# preview graph
G.nodes, G.edges
Out[10]:
(NodeView((1, 2, 3, 4, 5, 6, 20, 30)), EdgeView([(1, 2), (2, 3), (20, 30)]))
In [11]:
# create a linear (path) graph
H = nx.path_graph(10)
# add edge by another graph's edges
G.add_edges_from(H.edges)
# preview graph
G.nodes, G.edges
Out[11]:
(NodeView((1, 2, 3, 4, 5, 6, 20, 30, 0, 7, 8, 9)),
 EdgeView([(1, 2), (1, 0), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (20, 30), (7, 8), (8, 9)]))
In [12]:
# print the number of nodes and edges in the graph
G.number_of_nodes(), G.number_of_edges()
Out[12]:
(12, 10)
In [13]:
# remove all nodes and edges in the graph
G.clear()
# preview graph
G.nodes, G.edges
Out[13]:
(NodeView(()), EdgeView([]))

Create a Directed Graph¶

In [14]:
# create directed graph
DG = nx.DiGraph()
# add edges
DG.add_edge(2, 1)   # adds the nodes in order 2, 1
DG.add_edge(2, 3)
DG.add_edge(2, 4)
DG.add_edge(3, 2)
DG.add_edge(1, 3)
DG.add_edge(4, 3)
# preview graph
DG.nodes, DG.edges
Out[14]:
(NodeView((2, 1, 3, 4)),
 OutEdgeView([(2, 1), (2, 3), (2, 4), (1, 3), (3, 2), (4, 3)]))

Get Data from Graph¶

In [15]:
# list of nodes
list(DG.nodes)
Out[15]:
[2, 1, 3, 4]
In [16]:
# list of edges
list(DG.edges)
Out[16]:
[(2, 1), (2, 3), (2, 4), (1, 3), (3, 2), (4, 3)]
In [17]:
# list of a node's neighbors
list(DG.adj[1])
Out[17]:
[3]

Remove Node or Edge from a Graph¶

In [18]:
# remove a node
DG.remove_node(2)
list(DG.nodes)
Out[18]:
[1, 3, 4]
In [19]:
# remove an edge
DG.remove_edge(1, 3)
list(DG.edges)
Out[19]:
[(4, 3)]

Create Graph by Edgelist¶

In [20]:
# create graph by edgelist
edgelist = [(2, 1), (2, 3), (2, 4), (3, 2), (1, 3), (4, 3), (1, 2)]
G = nx.Graph(edgelist)
# preview graph
G.nodes(), G.edges()
Out[20]:
(NodeView((2, 1, 3, 4)), EdgeView([(2, 1), (2, 3), (2, 4), (1, 3), (3, 4)]))

Add attributes¶

In [21]:
# add attribute to edge
G[1][3]['color'] = "blue"
G.edges[1, 2]['color'] = "red"
# preview edge
G.edges[1, 2]
Out[21]:
{'color': 'red'}
In [22]:
# [method 1] add attribute [weight] to edge
G.edges[1, 2]['weight'] = 20
# preview edge
G.edges[1, 2]
Out[22]:
{'color': 'red', 'weight': 20}
In [23]:
# [method 2] add attribute [weight] to edge
G.add_edge(6, 7, weight=12)
# preview edge
G.edges[6, 7]
Out[23]:
{'weight': 12}
In [24]:
# [method 2] add attribute [weight] to edge
G.add_edges_from([(6, 1),(4, 5)], weight=15)
G.add_edges_from([(6, 2, {'weight': 8}), (3, 5, {'weight': 8})])
# preview edge
G.edges[6, 1], G.edges[6, 2]
Out[24]:
({'weight': 15}, {'weight': 8})

Testing a graph¶

In [25]:
# from undirected to direceted graph
DG_ = G.to_directed()
# preview edge
DG_.edges
Out[25]:
OutEdgeView([(2, 1), (2, 3), (2, 4), (2, 6), (1, 2), (1, 3), (1, 6), (3, 2), (3, 1), (3, 4), (3, 5), (4, 2), (4, 3), (4, 5), (6, 7), (6, 1), (6, 2), (7, 6), (5, 4), (5, 3)])
In [26]:
# from directed to undireceted graph
G_ = DG_.to_undirected()
# preview edge
G_.edges
Out[26]:
EdgeView([(2, 1), (2, 3), (2, 4), (2, 6), (1, 3), (1, 6), (3, 4), (3, 5), (4, 5), (6, 7)])

Create special graph¶

In [27]:
# create complete graph
comp_G = nx.complete_graph(10)
# preview graph
comp_G.nodes, comp_G.edges
Out[27]:
(NodeView((0, 1, 2, 3, 4, 5, 6, 7, 8, 9)),
 EdgeView([(0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (0, 9), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (1, 8), (1, 9), (2, 3), (2, 4), (2, 5), (2, 6), (2, 7), (2, 8), (2, 9), (3, 4), (3, 5), (3, 6), (3, 7), (3, 8), (3, 9), (4, 5), (4, 6), (4, 7), (4, 8), (4, 9), (5, 6), (5, 7), (5, 8), (5, 9), (6, 7), (6, 8), (6, 9), (7, 8), (7, 9), (8, 9)]))
In [28]:
# create Erdos Renyi graph
er_G = nx.erdos_renyi_graph(10, 0.5)
# preview graph
er_G.nodes, er_G.edges
Out[28]:
(NodeView((0, 1, 2, 3, 4, 5, 6, 7, 8, 9)),
 EdgeView([(0, 1), (0, 2), (0, 4), (0, 7), (0, 8), (0, 9), (1, 3), (1, 4), (1, 9), (2, 3), (2, 6), (2, 7), (2, 8), (3, 4), (3, 6), (3, 7), (3, 8), (4, 6), (4, 7), (4, 8), (4, 9), (5, 6), (5, 7), (6, 7), (6, 8), (7, 9), (8, 9)]))
In [29]:
# list of connected components
list(nx.connected_components(er_G))
Out[29]:
[{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}]
In [30]:
# list of shortest path
dict(nx.all_pairs_shortest_path(er_G))
Out[30]:
{0: {0: [0],
  1: [0, 1],
  2: [0, 2],
  4: [0, 4],
  7: [0, 7],
  8: [0, 8],
  9: [0, 9],
  3: [0, 1, 3],
  6: [0, 2, 6],
  5: [0, 7, 5]},
 1: {1: [1],
  0: [1, 0],
  3: [1, 3],
  4: [1, 4],
  9: [1, 9],
  2: [1, 0, 2],
  7: [1, 0, 7],
  8: [1, 0, 8],
  6: [1, 3, 6],
  5: [1, 0, 7, 5]},
 2: {2: [2],
  0: [2, 0],
  3: [2, 3],
  6: [2, 6],
  7: [2, 7],
  8: [2, 8],
  1: [2, 0, 1],
  4: [2, 0, 4],
  9: [2, 0, 9],
  5: [2, 6, 5]},
 3: {3: [3],
  1: [3, 1],
  2: [3, 2],
  4: [3, 4],
  6: [3, 6],
  7: [3, 7],
  8: [3, 8],
  0: [3, 1, 0],
  9: [3, 1, 9],
  5: [3, 6, 5]},
 4: {4: [4],
  0: [4, 0],
  1: [4, 1],
  3: [4, 3],
  6: [4, 6],
  7: [4, 7],
  8: [4, 8],
  9: [4, 9],
  2: [4, 0, 2],
  5: [4, 6, 5]},
 5: {5: [5],
  6: [5, 6],
  7: [5, 7],
  2: [5, 6, 2],
  3: [5, 6, 3],
  4: [5, 6, 4],
  8: [5, 6, 8],
  0: [5, 7, 0],
  9: [5, 7, 9],
  1: [5, 6, 3, 1]},
 6: {6: [6],
  2: [6, 2],
  3: [6, 3],
  4: [6, 4],
  5: [6, 5],
  7: [6, 7],
  8: [6, 8],
  0: [6, 2, 0],
  1: [6, 3, 1],
  9: [6, 4, 9]},
 7: {7: [7],
  0: [7, 0],
  2: [7, 2],
  3: [7, 3],
  4: [7, 4],
  5: [7, 5],
  6: [7, 6],
  9: [7, 9],
  1: [7, 0, 1],
  8: [7, 0, 8]},
 8: {8: [8],
  0: [8, 0],
  2: [8, 2],
  3: [8, 3],
  4: [8, 4],
  6: [8, 6],
  9: [8, 9],
  1: [8, 0, 1],
  7: [8, 0, 7],
  5: [8, 6, 5]},
 9: {9: [9],
  0: [9, 0],
  1: [9, 1],
  4: [9, 4],
  7: [9, 7],
  8: [9, 8],
  2: [9, 0, 2],
  3: [9, 1, 3],
  6: [9, 4, 6],
  5: [9, 7, 5]}}

Draw a graph¶

In [31]:
# visualize the graph
options = {
    "font_size": 14,
    "node_size": 800,
    "node_color": "#A0CBE2",
    "edge_color": "skyblue",
    "linewidths": 1,
    "width": 2,
}

plt.subplots(figsize=[12,4], dpi=300)
plt.subplot(131)
nx.draw_networkx(star,  **options, with_labels = True)
ax = plt.gca()
ax.margins(0.20)
plt.axis("off")
plt.title('Star Network', fontsize=18)

plt.subplot(132)
nx.draw_networkx(line,  **options, with_labels = True)
ax = plt.gca()
ax.margins(0.20)
plt.axis("off")
plt.title('Line Network', fontsize=18)

plt.subplot(133)
nx.draw_networkx(circle,  **options, with_labels = True)
ax = plt.gca()
ax.margins(0.20)
plt.axis("off")
plt.title('Circle Network', fontsize=18)

plt.show()
In [ ]: